/* loadLibP.h - private object module loader library header */

/*
 * Copyright (c) 2002-2005 Wind River Systems, Inc.
 *
 * The right to copy, distribute, modify or otherwise make use of this software
 * may be licensed only pursuant to the terms of an applicable Wind River
 * license agreement.
 */

/*
modification history
--------------------
01j,26jul05,v_r  Complete loader's XXX review.
01i,18mar05,v_r  Include cleanups + code conventions compliancy work.
		 Removed loadModuleByFilename() and loadModuleAtByFilename()
		 APIs.
01h,01mar05,v_r  Added pLoadRoutine() prototype.
01g,22feb05,dbt  Cleanup.
01f,06oct04,jn   Clean up comments
01e,21sep04,jn   Move shared macros for relocations out of relocation units
                 (elf<Arch>.c)
01d,18sep04,jn   Move towards shared code for host and target loaders
01c,16apr04,jn   Remove section directives - not useful right now
01b,02apr04,jn   Fix warning in bsp builds.  Clean up - remove unused 
                 declarations and development-related comments
01a,16may02,fmk  written
*/

#ifndef __INCloadLibPh
#define __INCloadLibPh

#ifdef __cplusplus
extern "C" {
#endif

/* Include */

#ifdef HOST
#include "sllLib.h"
#include "symbol.h"
#include "symLib.h"
#include "moduleLibP.h"
#include "pdLib.h"
#include "memAttrLib.h"
#include "private/moduleLibP.h" 
#include "private/loadElfLibP.h"
#include "private/loadFileLibP.h"
#include "moduleLib.h"
#include "loadLib.h"
#else
#include "loadFileLibP.h"
#include "private/moduleLibP.h"
#include "private/loadElfLibP.h"
#include "loadLib.h"
#endif /* HOST */

/* defines */

#define TEXT_SEG_INFO(pList)	((SEGMENT_INFO_DESC *)pList->head)
#define DATA_SEG_INFO(pList)	((SEGMENT_INFO_DESC *)pList->head->next)
#define BSS_SEG_INFO(pList)	((SEGMENT_INFO_DESC *)pList->head->next->next)

/* ALIGN_NEXT is defined in memPartLibP.h on the target. */

#ifdef HOST
#define ALIGN_NEXT(size,align)	((((UINT)(size)) + align - 1) & (~(align - 1)))
#endif /* HOST */


/* Swap of two bytes : AB becomes BA */

#define SWAB_16(x)	(((UINT16)((x) & 0x00ff) << 8) | \
			 ((UINT16)((x) & 0xff00) >> 8))

/* Swap of four bytes : ABCD becomes DCBA */

#define SWAB_32(x)	(((UINT32)((x) & 0x000000ff) << 24) | \
			 ((UINT32)((x) & 0x0000ff00) << 8)  | \
			 ((UINT32)((x) & 0x00ff0000) >> 8)  | \
			 ((UINT32)((x) & 0xff000000) >> 24))

/* Swap only if the boolean (b) is true */

#define SWAB_16_IF(b,v)		((v) = ((b) ? SWAB_16 (v) : (v)))
#define SWAB_32_IF(b,v)		((v) = ((b) ? SWAB_32 (v) : (v)))

#ifdef HOST
#define MEM_READ_32(pRelocAdrs, offset)                             \
    do                                                              \
        {                                                           \
        if (tgtMemRead (NULL, (pRelocAdrs), &(offset),              \
			sizeof(UINT32), 0, 0) != OK)                \
	    return ERROR;                                           \
        SWAB_32_IF (swapIsRequired, offset);	/* Host format */   \
        }                                                           \
    while (0);

#define MEM_READ_16(pRelocAdrs, offset)                             \
    do                                                              \
        {                                                           \
        if (tgtMemRead (NULL, (pRelocAdrs), &(offset),              \
                       sizeof(UINT16), 0, 0) != OK)                 \
            return ERROR;                                           \
        SWAB_16_IF (swapIsRequired, offset);	/* Host format */   \
        } while (0);

#define MEM_READ_8(pRelocAdrs, offset)                              \
    do                                                              \
        {                                                           \
        if (tgtMemRead (NULL, (pRelocAdrs), &(offset),              \
                        sizeof(UINT8), 0, 0) != OK)                 \
            return ERROR;                                           \
        } while (0);

#define MEM_WRITE_32(pRelocAdrs, value32)                           \
    do                                                              \
        {                                                           \
        SWAB_32_IF (swapIsRequired, value32); /* Target format */   \
        if (tgtMemManyWrite (NULL, &(value32), (pRelocAdrs),        \
                             sizeof (UINT32)) != OK)                \
            return ERROR;                                           \
        } while (0); 

#define MEM_WRITE_16(pRelocAdrs, value16)                           \
    do                                                              \
        {                                                           \
        SWAB_16_IF (swapIsRequired, value16);	/* Target format */ \
        if (tgtMemManyWrite (NULL, &(value16), (pRelocAdrs),        \
                             sizeof(UINT16)) != OK)                 \
            return ERROR;                                           \
        } while (0);

#define MEM_WRITE_8(pRelocAdrs, value)					\
    do                                                              \
        {                                                           \
        if (tgtMemManyWrite (NULL, &value, pRelocAdrs, sizeof (UINT8)) != OK) \
	    return ERROR;                                           \
        } while (0);



#else

#define MEM_READ_32(pRelocAdrs, offset)	((offset) = *((UINT32 *)(pRelocAdrs)));
#define MEM_READ_16(pRelocAdrs, offset)	((offset) = *((UINT16 *)(pRelocAdrs)));
#define MEM_READ_8(pRelocAdrs, offset)  ((offset) = *((UINT8 *)(pRelocAdrs)));

#define MEM_WRITE_32(pRelocAdrs, value32)	\
	(*((UINT32 *)(pRelocAdrs)) = (value32));
#define MEM_WRITE_16(pRelocAdrs, value16)	\
	(*((UINT16 *)(pRelocAdrs)) = (value16));
#define MEM_WRITE_8(pRelocAdrs, value8)         \
    (*((UINT8 *)(pRelocAdrs)) = (value8));

#endif /* HOST/!HOST */

/* misc definitions */

/* Macro to check if the alignment is a power of 2 */

#define CHECK_2_ALIGN(x)        (((x) & ((x) - 1)) == 0)

/* Macros used for performing relocations */

#define LOAD_LOW24_INSERT(buf,value)	INSERT ((buf), (value), 0x00ffffff)

/* type definitions */

typedef struct
    {
    char *	symName;            /* common symbol's name               */
    BOOL	vxWorksSymMatched;  /* TRUE if core syms are included     */
    void *      pSymAddrComm;	    /* Matching comm sym's addr, if any   */
    SYM_TYPE    commSymType;	    /* Exact type of matching comm symbol */
    void *	pSymAddrBss;	    /* matching bss sym's addr, if any    */
    SYM_TYPE	bssSymType;	    /* exact type of matching bss symbol  */
    void *	pSymAddrData;	    /* matching data sym's addr, if any   */
    SYM_TYPE	dataSymType;	    /* exact type of matching data symbol */
    void *      pSymAddrText;	    /* Matching text sym's addr, if any   */
    SYM_TYPE    textSymType;	    /* Exact type of matching text symbol */
    UINT32	commStrategy;	    /* Strategy used for comm management  */
    } COMMON_INFO;

/* externals */

extern FUNCPTR	syncLoadRtn;

/* function declarations */

/* 
 * The following function was written to be called from usrLoadSym.c. 
 * It requires the arguments used in usrLoadSym for the network system symbol
 * table and its various users (such as the shell) to behave as documented. 
 */

extern STATUS	loadSysSymTblLoad (int symfd, int flags);
extern STATUS	loadCommonManage (int comAreaSize, int comAlignment,
				  char * symName, SYMTAB_ID symTbl,
				  SYM_ADRS * pSymAddr, SYM_TYPE * pSymType,
				  int loadFlag, SEG_INFO * pSeg, int group);
extern STATUS	loadCommonMatch (COMMON_INFO * pCommInfo, SYMTAB_ID symTblId);
extern STATUS	loadUndefinedSymbolProcess (char * name, SYM_INFO * pSymInfo,
					    MODULE_ID moduleId); 
extern STATUS	loadCommonSymbolProcess (char * name, UINT symSize,
					 UINT symAlign, SYM_INFO * pSymInfo,
					 MODULE_ID moduleId, int loadFlag);
extern STATUS	loadDefinedSymbolProcess (char * name, SYM_ADRS symAddr,
					  SYM_EXT_TYPE symExtType,
					  SYM_INFO * pSymInfo,
					  MODULE_ID moduleId,
					  int loadFlag);
extern void	loadBuffersFree (void * pBuf);
extern STATUS	loadSectionDirectiveMatch (UINT nbSegDirectives,
					LOAD_SEGMENT_DIRECTIVE * pSegDirective,
					   SL_LIST * pSegInfoList,
					   SECTION_INFO_DESC * pScnInfo,
					   BOOL * pScnMatches); 
extern STATUS	loadSegmentsAllocate (MODULE_ID moduleId,
				      LOAD_FLAG_T loadFlags,
				      SL_LIST * pMemInfoList);
extern STATUS	loadSectionsInstall (LOAD_MODULE_INFO * pLoadModuleInfo,
				     LOAD_FLAG_T loadFlags,
				     SL_LIST * pSegInfoList);
extern STATUS	loadSegInfoDescAllocate (SL_LIST * pSegInfoDescList,
					 LOAD_FLAG_T loadFlags,
					LOAD_SEGMENT_DIRECTIVE * pSegDirective,
					 UINT nbSegDirectives);
extern STATUS	loadSegInfoDescFree (SL_LIST * pSegInfoDescList); 
extern STATUS	(* pLoadRoutine) (LOAD_MODULE_INFO *, LOAD_FLAG_T,
				  LOAD_SEGMENT_DIRECTIVE *, UINT,
				  MODULE_ID, BOOL *);

#ifdef __cplusplus
}
#endif

#endif /* __INCloadLibPh */




